/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include <stdafx.h>
#include <set>
#include "Vulkan框架.h"



#include <vulkan/vulkan_win32.h>


#pragma comment(lib, "D:/U/DEV/VulkanSDK/Lib/vulkan-1.lib")
#pragma comment(lib, "D:/U/DEV/VulkanSDK/Lib/OSDependentd.lib")
#pragma comment(lib, "D:/U/DEV/VulkanSDK/Lib/shaderc.lib")
#pragma comment(lib, "D:/U/DEV/VulkanSDK/Lib/spirv-cross-cd.lib")
#pragma comment(lib, "D:/U/DEV/VulkanSDK/Lib/spirv-cross-glsld.lib")
#pragma comment(lib, "D:/U/DEV/VulkanSDK/Lib/SPIRV-Toolsd.lib")
#pragma comment(lib, "D:/U/DEV/VulkanSDK/Lib/SPIRV-Tools-linkd.lib")
#pragma comment(lib, "D:/U/DEV/VulkanSDK/Lib/SPVRemapperd.lib")


#include "buffer/Vk图像.h"
#include "底层绘图/底层绘图框架.h"
#include "纹理/纹理.h"


#define FENCE_TIMEOUT 100000000

 

static VkDebugReportCallbackEXT callback;

static VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const
	VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback) {
	auto func = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT");

	if (func != nullptr) {
		return func(instance, pCreateInfo, pAllocator, pCallback);
	}
	else {
		return VK_ERROR_EXTENSION_NOT_PRESENT;
	}
}

static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char* layerPrefix, const char* msg, void* userData) {
	std::cerr << "validation layer: " << layerPrefix << "__" << msg << std::endl;
	std::cerr << "validation layer location: " << location << "__" << code << " : " << objType << std::endl;
	return VK_FALSE;
}

void DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator) {
	auto func = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT");
	if (func != nullptr) {
		func(instance, callback, pAllocator);
	}
}

static bool f_检查设备扩展支持(const VkPhysicalDevice& gpu, const vector<const char*>& extensions) {
	uint32_t extensionCount;
	vkEnumerateDeviceExtensionProperties(gpu, nullptr, &extensionCount, nullptr);

	vector<VkExtensionProperties> availableExtensions(extensionCount);
	vkEnumerateDeviceExtensionProperties(gpu, nullptr, &extensionCount, availableExtensions.data());

	std::set<string> requiredExtensions(extensions.begin(), extensions.end());
	for (const auto& extension : availableExtensions) {
		auto a = requiredExtensions.erase(extension.extensionName);
		if (a) {
			DEF_记录日志("vulkan 支持扩展:" + std::to_string(uint64(gpu)) + " " + std::string(extension.extensionName));
			cout << "支持扩展:" << extension.extensionName << endl;
		}
	}

	return requiredExtensions.empty();
}

static VkFormat f_vk_取窗口面支持像素格式(VkPhysicalDevice& 物理设备, VkSurfaceKHR& surface) {
	uint32 格式支持数量 = 0;
	VkResult res = vkGetPhysicalDeviceSurfaceFormatsKHR(物理设备, surface, &格式支持数量, NULL);
	assert(res == VK_SUCCESS);
	vector<VkSurfaceFormatKHR> 格式(格式支持数量);
	res = vkGetPhysicalDeviceSurfaceFormatsKHR(物理设备, surface, &格式支持数量, 格式.data());
	assert(res == VK_SUCCESS);

	if (格式支持数量 == 1 && 格式[0].format == VK_FORMAT_UNDEFINED) {
		return VK_FORMAT_B8G8R8A8_UNORM;
	}

	assert(格式支持数量 >= 1);
	return 格式[0].format;
}

static VkFormat f_vk_取设备支持像素格式(VkPhysicalDevice& 物理设备, VkSurfaceKHR& surface) {
	uint32 格式支持数量 = 0;
	VkResult res = vkGetPhysicalDeviceSurfaceFormatsKHR(物理设备, surface, &格式支持数量, NULL);
	assert(res == VK_SUCCESS);
	vector<VkSurfaceFormatKHR> 格式(格式支持数量);
	res = vkGetPhysicalDeviceSurfaceFormatsKHR(物理设备, surface, &格式支持数量, 格式.data());
	assert(res == VK_SUCCESS);

	if (格式支持数量 == 1 && 格式[0].format == VK_FORMAT_UNDEFINED) {
		return VK_FORMAT_B8G8R8A8_UNORM;
	}
	assert(格式支持数量 >= 1);
	return 格式[0].format;
}

S_VK框架::S_VK框架() {
	m_Type = E_绘图API::E_Vulkan;
	m_开启光追 = true;
	auto ExNameRTX = { 
		VK_KHR_SWAPCHAIN_EXTENSION_NAME, 
		VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
		
		//VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
		//VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME,
		//VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME,
		//VK_KHR_RAY_QUERY_EXTENSION_NAME,
		//VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME,
		//VK_NV_RAY_TRACING_EXTENSION_NAME, 
	};

	if (f_创建实例() == false) return;

	f_枚举物理设备(ExNameRTX);

	m_是否有光追支持 = false;

}

S_VK框架::~S_VK框架() {
#ifdef _DEBUG
	DestroyDebugReportCallbackEXT(m_Instance, callback, m_allocator);
#endif

	f_销毁实例(m_Instance);
}


bool S_VK框架::f_releaseVK() {
	for (auto& key : m_逻辑设备) {
		for (auto& e : key.second) {
			vkDeviceWaitIdle(e.m_Device);
			vkDestroyDevice(e.m_Device, m_allocator);
		}
	}

	if (m_Instance) {
		vkDestroyInstance(m_Instance, NULL);
	}
	return true;
}



vector<const char*> f_检查验证层支持() {
	uint32_t layerCount;
	vkEnumerateInstanceLayerProperties(&layerCount, nullptr);

	static std::vector<VkLayerProperties> availableLayers;
	availableLayers.resize(layerCount);
	vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());


	vector<const char*> 检查验证层名称;
	//vector<string> 扩展名称;
	for (const auto& e : availableLayers) {
		//扩展名称.push_back(e.layerName);
		cout << "availableLayers:" << e.layerName << endl;
		检查验证层名称.push_back(e.layerName);
	}

	return 检查验证层名称;
}

static vector<VkQueueFamilyProperties> f_vk_罗列物理设备列队家族(VkPhysicalDevice& 物理设备) {
	uint32 列队家族数量 = 0;
	vector<VkQueueFamilyProperties> 列队家族;

	VkPhysicalDeviceMemoryProperties 物理设备内存属性;
	vkGetPhysicalDeviceMemoryProperties(物理设备, &物理设备内存属性);


	vkGetPhysicalDeviceQueueFamilyProperties(物理设备, &列队家族数量, 0);
	列队家族.resize(列队家族数量);
	vkGetPhysicalDeviceQueueFamilyProperties(物理设备, &列队家族数量, 列队家族.data());


	return 列队家族;
}

static bool f_vk_创建交换链(S_设备环境& 设备环境, S_vk_window& ws, uvec2& size, VkSwapchainKHR old_swapchain) {
	VkResult res;
	auto dc = f_vk_get绘图环境(设备环境);

	VkSurfaceCapabilitiesKHR 交换面功能 = {};
	res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(dc->m_物理设备, ws.m_vk_surface, &交换面功能);
	assert(res == VK_SUCCESS);
	uint32 当前模式数量 = 0;
	res = vkGetPhysicalDeviceSurfacePresentModesKHR(dc->m_物理设备, ws.m_vk_surface, &当前模式数量, NULL);
	assert(res == VK_SUCCESS);
	vector<VkPresentModeKHR> 当前模式(当前模式数量);
	res = vkGetPhysicalDeviceSurfacePresentModesKHR(dc->m_物理设备, ws.m_vk_surface, &当前模式数量, 当前模式.data());
	assert(res == VK_SUCCESS);

	VkPresentModeKHR 交换链呈现模式 = VK_PRESENT_MODE_FIFO_KHR;
	for (size_t i = 0; i < 当前模式数量; i++) {
		//如果也支持VK_PRESENT_MODE_MAILBOX_KHR模式，由于其效率高，便选用
		if (当前模式[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
			交换链呈现模式 = VK_PRESENT_MODE_MAILBOX_KHR;
			break;
		}
		if ((交换链呈现模式 != VK_PRESENT_MODE_MAILBOX_KHR) && (当前模式[i] == VK_PRESENT_MODE_IMMEDIATE_KHR)) {
			交换链呈现模式 = VK_PRESENT_MODE_IMMEDIATE_KHR;
		}
	}


	if (size.x < 交换面功能.minImageExtent.width) {
		size.x = 交换面功能.minImageExtent.width;
	}
	else if (size.x > 交换面功能.maxImageExtent.width) {
		size.x = 交换面功能.maxImageExtent.width;
	}

	if (size.y < 交换面功能.minImageExtent.height) {
		size.y = 交换面功能.minImageExtent.height;
	}
	else if (size.y > 交换面功能.maxImageExtent.height) {
		size.y = 交换面功能.maxImageExtent.height;
	}

	VkSurfaceTransformFlagBitsKHR preTransform;
	if (交换面功能.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) {
		preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
	}
	else {
		preTransform = 交换面功能.currentTransform;
	}


	//////////////////////////////////////////////////////////////////////////////////
	//								查找支持透明模式								//
	//////////////////////////////////////////////////////////////////////////////////
	VkCompositeAlphaFlagBitsKHR 透明通道混合模式 = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
	VkCompositeAlphaFlagBitsKHR compositeAlphaFlags[4] = {
		VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR,
		VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR,
		VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
		VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR,
	};
	for (uint32_t i = 0; i < sizeof(compositeAlphaFlags); i++) {
		if (交换面功能.supportedCompositeAlpha & compositeAlphaFlags[i]) {
			透明通道混合模式 = compositeAlphaFlags[i];
			break;
		}
	}


	//绘图设备配置.m_深度图像格式 = f_findDepthFormat(绘图设备配置.m_物理设备);
	VkSwapchainCreateInfoKHR 交换链创建信息 = {};
	交换链创建信息.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
	交换链创建信息.pNext = NULL;
	交换链创建信息.surface = ws.m_vk_surface;
	交换链创建信息.imageFormat = f_vk_取窗口面支持像素格式(dc->m_物理设备, ws.m_vk_surface);
	交换链创建信息.minImageCount = 交换面功能.minImageCount;
	交换链创建信息.imageExtent.width = size.x;
	交换链创建信息.imageExtent.height = size.y;
	交换链创建信息.preTransform = preTransform;
	交换链创建信息.compositeAlpha = 透明通道混合模式;
	交换链创建信息.imageArrayLayers = 1;
	交换链创建信息.presentMode = 交换链呈现模式;
	交换链创建信息.oldSwapchain = VK_NULL_HANDLE;
	交换链创建信息.clipped = true;
	交换链创建信息.imageColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;								//色彩空间
	交换链创建信息.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT;	//图像用途
	交换链创建信息.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;									//图像共享模式
	交换链创建信息.queueFamilyIndexCount = 0;
	交换链创建信息.pQueueFamilyIndices = NULL;
	交换链创建信息.oldSwapchain = old_swapchain;

	uint32 queueFamilyIndices[2] = { dc->绘图列队家族Offset, dc->交换链列队家族Offset };
	if (queueFamilyIndices[0] != queueFamilyIndices[1]) {
		交换链创建信息.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
		交换链创建信息.queueFamilyIndexCount = 2;
		交换链创建信息.pQueueFamilyIndices = queueFamilyIndices;
	}

	res = vkCreateSwapchainKHR(dc->m_设备, &交换链创建信息, NULL, &ws.m_vk_swapchain);
	assert(res == VK_SUCCESS);
	if (res != VK_SUCCESS) {
		DEF_记录日志("创建交换链失败");
		return false;
	}

	return true;
}

static void f_vk_重置交换链图像(S_设备环境& 设备环境, S_vk_window& ws, uvec2 size, uint32 交换链数量) {
	VkResult       res;
	auto dc = f_vk_get绘图环境(设备环境);

	VkImage* 交换链图像 = (VkImage*)malloc(交换链数量 * sizeof(VkImage));
	res = vkGetSwapchainImagesKHR(dc->m_设备, ws.m_vk_swapchain, &交换链数量, 交换链图像);
	if (res != VK_SUCCESS) {
		DEF_记录日志("创建交换链纹理对象失败" + std::to_string(res) + " " + std::string(__FILE__) + " 行:" + std::to_string(__LINE__));
	}
	assert(res == VK_SUCCESS);
	


	auto 图像格式 = f_vk_取设备支持像素格式(dc->m_物理设备, ws.m_vk_surface);
	uvec3 图像大小 = { size.x , size.y, 1 };

	for (uint32_t i_交换链图像 = 0; i_交换链图像 < 交换链数量; ++i_交换链图像) {
		S_VkImage* texCol = S_Vk图像管理::f_创建图像视图(dc->m_设备, 交换链图像[i_交换链图像], 图像格式, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
		ws.m_交换面颜色缓存[i_交换链图像] = (texCol);
	}
}

static void f_vk_创建交换链绘制缓存(S_设备环境& 设备环境, S_vk_window& ws, uvec2 size, bool 深度) {
	VkResult       res;
	auto dc = f_vk_get绘图环境(设备环境);

	uint32 交换链数量 = 0;
	res = vkGetSwapchainImagesKHR(dc->m_设备, ws.m_vk_swapchain, &交换链数量, NULL);
	if (res != VK_SUCCESS) {
		DEF_记录日志("创建交换链纹理对象失败" + std::to_string(res) + " " + std::string(__FILE__) + " 行:" + std::to_string(__LINE__));
	}
	assert(res == VK_SUCCESS);

	
	ws.m_交换面颜色缓存 = (S_纹理**)calloc(交换链数量, sizeof(S_VkImage*));
	f_vk_重置交换链图像(设备环境, ws, size, 交换链数量);

	if (dc->m_窗口UI合成通道 == nullptr) {
		dc->m_窗口UI合成通道 = f_fb_创建渲染通道(dc->m_设备, dc->m_颜色图像格式, true);
	}

	ws.m_Frame = f_fb_创建UI合成帧缓存(设备环境, 交换链数量, size, ws.m_交换面颜色缓存);
	ws.m_Frame->m_颜色通道数量 = 1;
	
}

static bool f_createSwapchain(S_设备环境& 设备环境, S_vk_window& ws, uvec2 size) {
	VkResult res;
	auto dc = f_vk_get绘图环境(设备环境);

	vector<VkQueueFamilyProperties> 列队家族 = f_vk_罗列物理设备列队家族(dc->m_物理设备);
	uint32 列队家族数量 = 列队家族.size();

	//物理设备 交换链家族id 是否支持交换链
	vector<VkBool32> 是否支持交换链(列队家族数量);
	for (uint32 i = 0; i < 列队家族数量; ++i) {
		res = vkGetPhysicalDeviceSurfaceSupportKHR(dc->m_物理设备, i, ws.m_vk_surface, &是否支持交换链[i]);
		if (res != VK_SUCCESS) {
			cout << "vkGetPhysicalDeviceSurfaceSupportKHR error" << endl;
		}
	}

	//////////////////////////////////////////////////////////////////////////
	//					 挑选绘图类和交换链类偏移ID							//
	//////////////////////////////////////////////////////////////////////////
	dc->绘图列队家族Offset = UINT32_MAX;
	dc->交换链列队家族Offset = UINT32_MAX;
	for (uint32 i = 0; i < 列队家族数量; ++i) {
		if (列队家族[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
			if (dc->绘图列队家族Offset == UINT32_MAX) dc->绘图列队家族Offset = i;

			if (是否支持交换链[i]) {
				dc->交换链列队家族Offset = i;
				break;
			}
		}
	}

	if (dc->交换链列队家族Offset == UINT32_MAX || dc->交换链列队家族Offset == UINT32_MAX) {
		DEF_记录日志("设备不支持显示");
		std::cout << "设备不支持显示" << endl;
		return false;
	}


	f_vk_创建交换链(设备环境, ws, size, 0);
	f_vk_创建交换链绘制缓存(设备环境, ws, size, false);
	return true;
}

static void f_vk_重置交换链(S_设备环境& 设备环境, S_vk_window& ws, uvec2 size) {
	VkResult       res;
	auto dc = f_vk_get绘图环境(设备环境);

	VkSwapchainKHR old_swapchain = ws.m_vk_swapchain;
	//res = vkDeviceWaitIdle(绘图设备.m_设备);
	//assert(res == VK_SUCCESS);


	//销毁久的帧缓存
	S_Vk帧缓存& vf = *(S_Vk帧缓存*)ws.m_Frame;
	vf.f_release(true);

	f_vk_创建交换链(设备环境, ws, size, ws.m_vk_swapchain);

	if (old_swapchain) {
		vkDestroySwapchainKHR(dc->m_设备, old_swapchain, nullptr);
	}

	f_vk_创建交换链绘制缓存(设备环境, ws, size, false);
}





bool S_VK框架::f_创建实例() {
	m_Instance = {};


	//扩展名称获取必须在最前面 否则导致实例创建失败
	uint32 实例扩展层数量 = 0;
	vkEnumerateInstanceExtensionProperties(0, &实例扩展层数量, 0);
	vector<const char*> 实例扩展层名称(实例扩展层数量);
	vector<VkExtensionProperties> 层属性(实例扩展层数量);
	if (实例扩展层数量) {
		vkEnumerateInstanceExtensionProperties(0, &实例扩展层数量, 层属性.data());
	}
	for (uint32 i = 0; i < 实例扩展层数量; ++i) {
		实例扩展层名称[i] = 层属性[i].extensionName;
	}
	//实例扩展层名称.push_back("VK_KHR_get_physical_device_properties2");



	
	auto 版本 = VK_MAKE_VERSION(1, 3, 0);
	VkApplicationInfo appInfo = {};

	appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
	appInfo.pNext = NULL;
	appInfo.pApplicationName = "mbt vulkan engine";
	appInfo.applicationVersion = 版本;
	appInfo.pEngineName = "mbt engine";
	appInfo.engineVersion = 版本;
	appInfo.apiVersion = 版本;


	VkInstanceCreateInfo 实例创建信息 = {};
	实例创建信息.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
	实例创建信息.pApplicationInfo = &appInfo;
	实例创建信息.flags = VkInstanceCreateFlags();


#ifdef _DEBUG
	auto 验证层 = f_检查验证层支持();

	const char* layers[] = { 
							//"VK_LAYER_NV_optimus",
							//"VK_LAYER_NV_nsight",
							//"VK_LAYER_NV_nsight-sys",
							//"VK_LAYER_VALVE_steam_overlay",
							//"VK_LAYER_NV_optimus",
							//"VK_LAYER_NV_nsight",
							//"VK_LAYER_VALVE_steam_fossilize",
							//"VK_LAYER_EOS_Overlay",
							//"VK_LAYER_NV_nsight-sys",
							"VK_LAYER_KHRONOS_synchronization2",
							"VK_LAYER_KHRONOS_validation",
							
							"VK_LAYER_KHRONOS_shader_object",
							"VK_LAYER_KHRONOS_synchronization2",
							//"VK_LAYER_KHRONOS_profiles",

							"VK_LAYER_LUNARG_device_simulation",
							"VK_LAYER_LUNARG_monitor",
							"VK_LAYER_LUNARG_api_dump",
							
							
							"VK_LAYER_LUNARG_vktrace",
							"VK_LAYER_LUNARG_core_validation",
							};
	实例创建信息.ppEnabledLayerNames = layers;
	实例创建信息.enabledLayerCount = 4;

#endif

	实例创建信息.enabledExtensionCount = 实例扩展层名称.size();
	实例创建信息.ppEnabledExtensionNames = 实例扩展层名称.data();


	VkResult res;
	res = vkCreateInstance(&实例创建信息, m_allocator, &m_Instance);
	if (res == VK_ERROR_INCOMPATIBLE_DRIVER) {
		DEF_记录日志("创建实例失败 VK_ERROR_INCOMPATIBLE_DRIVER");
		cout << "create instance error VK_ERROR_INCOMPATIBLE_DRIVER" << endl;
		return false;
	} else if (res == VK_ERROR_EXTENSION_NOT_PRESENT) {
		DEF_记录日志("创建实例失败 VK_ERROR_EXTENSION_NOT_PRESENT");
		cout << "create instance error VK_ERROR_EXTENSION_NOT_PRESENT" << endl;
		return false;
	} else if (res) {
		DEF_记录日志("创建实例失败 VK_ERROR_EXTENSION_NOT_PRESENT" + std::to_string(res));
		cout << "create instance error" << endl;
		return false;
	}



#ifdef _DEBUG
	VkDebugReportCallbackCreateInfoEXT createInfo = {};
	createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
	createInfo.flags = VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT | VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_DEBUG_BIT_EXT;
	createInfo.pfnCallback = debugCallback;
	
	if (CreateDebugReportCallbackEXT(m_Instance, &createInfo, m_allocator, &callback) != VK_SUCCESS) {
		throw std::runtime_error("failed to set up debug callback!");
	}
#endif
	
	vkCmdSetSampleLocationsEXT = (PFN_vkCmdSetSampleLocationsEXT)vkGetInstanceProcAddr(m_Instance, "vkCmdSetSampleLocationsEXT");

	return true;
}

bool S_VK框架::f_枚举物理设备(const vector<const char*>& 光追扩展) {
	VkResult res;

	uint32 物理设备数量 = 0;
	res = vkEnumeratePhysicalDevices(m_Instance, &物理设备数量, 0);

	if (!物理设备数量) {
		DEF_记录日志("没有物理失败" + std::to_string(res));
		cout << "vulkne no dev:" << res << endl;
		return false;
	}

	vector<VkPhysicalDevice> 物理设备(物理设备数量);
	res = vkEnumeratePhysicalDevices(m_Instance, &物理设备数量, 物理设备.data());


	m_内存属性组.resize(物理设备数量);
	m_物理设备属性.resize(物理设备数量);
	m_物理光追设备属性.resize(物理设备数量);



//#ifdef _DEBUG
	cout << "PhysicalDevice:" << 物理设备数量 << endl;
//#endif

	int32 支持的设备ID = 0;
	for(uint32 i=0; i< 物理设备数量; ++i){
		vkGetPhysicalDeviceMemoryProperties(物理设备[i], &m_内存属性组[i]);
		
		auto ExName = { 
			VK_KHR_SWAPCHAIN_EXTENSION_NAME,
			
			VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME,
			VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME,
			VK_KHR_SPIRV_1_4_EXTENSION_NAME,
			VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME,
			VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME,
			VK_KHR_SHADER_CLOCK_EXTENSION_NAME,
			VK_KHR_16BIT_STORAGE_EXTENSION_NAME,
			VK_KHR_8BIT_STORAGE_EXTENSION_NAME,
			//VK_PROPERTY_FLAG_ATOMIC_FLOAT32,
			//VK_KHR_DEVICE_MEMORY_REPORT_EXTENSION_NAME,
			//VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME
			//VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME,
		};

		if (f_检查设备扩展支持(物理设备[i], ExName)) {
			
		}
		else {
			continue;
		}


		S_物理设备属性* prop = (S_物理设备属性*)malloc(sizeof(S_物理设备属性));

		vkGetPhysicalDeviceProperties(物理设备[i], &m_物理设备属性[i]);
		m_物理光追设备属性[i] = {};
		m_物理光追设备属性[i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR;
		m_物理光追设备属性[i].pNext = nullptr;
		m_物理光追设备属性[i].maxRecursionDepth = 0;
		m_物理光追设备属性[i].shaderGroupHandleSize = 0;
		VkPhysicalDeviceProperties2 props;
		props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
		props.pNext = &m_物理光追设备属性[i];
		props.properties = {};

		vkGetPhysicalDeviceProperties2(物理设备[i], &props);
		prop->m_光追设备属性 = *((VkPhysicalDeviceRayTracingPropertiesNV*)props.pNext);
		prop->m_光追设备属性.maxRecursionDepth;
		

		m_是否有光追支持 = true;
		if (prop->m_光追设备属性.maxRecursionDepth >= 1) {
			prop->m_支持光追 = true;
			cout << "vulkan get:" << i << " Ray Device" << endl;
			
		}
		else {
			cout << "vulkan get:" << i << " no Ray Device" << endl;
			DEF_记录日志("vulkan 没有光追设备" + std::to_string(i));
			prop->m_支持光追 = false;
		}


		

		m_设备.push_back({});
		auto& 支持的设备 = m_设备[支持的设备ID];
		支持的设备.物理设备.设备 = (S_结构指针)物理设备[i];
		支持的设备.物理设备.ID = i;


		prop->m_内存属性 = m_内存属性组[i];
		prop->m_设备属性 = m_物理设备属性[i];

		/**********************************************
		*                 取设备属性信息
		***********************************************/
		prop->m_多次采样最大值 = DEF_Min(m_物理设备属性[i].limits.framebufferColorSampleCounts, m_物理设备属性[i].limits.framebufferDepthSampleCounts);
		prop->m_最大几何输出顶点 = m_物理设备属性[i].limits.maxGeometryOutputVertices;
		prop->m_3D纹理最大分辨率 = m_物理设备属性[i].limits.maxImageDimension3D;
		prop->m_nonCoherentAtomSize = m_物理设备属性[i].limits.nonCoherentAtomSize;

		//VkPhysicalDeviceLimits::maxViewportDimensions[1]

		//m_物理设备属性[i].limits.framebufferColorSampleCounts;
		//m_物理设备属性[i].limits.storageImageSampleCounts;

		cout << "vulkan maxBoundDescriptorSets:" << m_物理设备属性[i].limits.maxBoundDescriptorSets << std::endl;

		支持的设备.物理设备.物理设备属性 = (S_结构指针)prop;

		++支持的设备ID;
	}

	return true;
}




int32 S_VK框架::f_选择列队族(vector<VkQueueFamilyProperties>& 列队族, uint32 flags) {
	QueueFamilyIndices indices;

	for (uint32 i = 0; i < 列队族.size(); ++i) {
		if (列队族[i].queueFlags & flags) {
			return i;
		}
	}
	return -1;
}







S_物理设备 S_VK框架::f_取物理设备(uint8 id) {
	return m_设备[id].物理设备;
}

S_逻辑设备 S_VK框架::f_创建图形逻辑设备(S_物理设备& dev, bool 是否有光追支持) {
	VkPhysicalDevice 物理设备 = (VkPhysicalDevice)dev.设备;
	S_物理设备属性* prop = (S_物理设备属性*)dev.物理设备属性;

	
	vector<VkQueueFamilyProperties> 列队家族 = f_罗列物理设备列队家族(物理设备);
	uint32 列队家族数量 = 列队家族.size();


	S_逻辑设备 逻辑设备 = { 0, -1 };

	for (uint16 i = 0; i < 列队家族数量; ++i) {
		if (列队家族[i].queueFlags & VK_QUEUE_COMPUTE_BIT && 列队家族[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
			逻辑设备.队列族索引 = i;
			break;
		}
	}

	if (逻辑设备.队列族索引 < 0) return {0, -1};



	//传统设备特性
	VkPhysicalDeviceFeatures 支持的特性{};
	//VkPhysicalDeviceFeatures 启用功能 = {};
	vkGetPhysicalDeviceFeatures(物理设备, &支持的特性);

	DEF_记录日志("vulkan multiDrawIndirect" + std::to_string(支持的特性.multiDrawIndirect));
	DEF_记录日志("vulkan geometryShader" + std::to_string(支持的特性.geometryShader));
	DEF_记录日志("vulkan samplerAnisotropy" + std::to_string(支持的特性.samplerAnisotropy));
	DEF_记录日志("vulkan imageCubeArray" + std::to_string(支持的特性.imageCubeArray));
	DEF_记录日志("vulkan shaderInt64" + std::to_string(支持的特性.shaderInt64));
	DEF_记录日志("vulkan shaderInt16" + std::to_string(支持的特性.shaderInt16));
	DEF_记录日志("vulkan shaderStorageImageMultisample" + std::to_string(支持的特性.shaderStorageImageMultisample));
	DEF_记录日志("vulkan fragmentStoresAndAtomics" + std::to_string(支持的特性.fragmentStoresAndAtomics));
	DEF_记录日志("vulkan independentBlend" + std::to_string(支持的特性.independentBlend));
	DEF_记录日志("vulkan drawIndirectFirstInstance" + std::to_string(支持的特性.drawIndirectFirstInstance));
	DEF_记录日志("vulkan tessellationShader" + std::to_string(支持的特性.tessellationShader));
	DEF_记录日志("vulkan fillModeNonSolid" + std::to_string(支持的特性.fillModeNonSolid));
	DEF_记录日志("vulkan wideLines" + std::to_string(支持的特性.wideLines));
	DEF_记录日志("vulkan sampleRateShading" + std::to_string(支持的特性.sampleRateShading));
	DEF_记录日志("vulkan depthClamp" + std::to_string(支持的特性.depthClamp));


	支持的特性.multiDrawIndirect						= 支持的特性.multiDrawIndirect;
	支持的特性.drawIndirectFirstInstance				= true;
	支持的特性.tessellationShader						= VK_TRUE;
	支持的特性.geometryShader							= VK_TRUE;
	支持的特性.fillModeNonSolid							= true;
	支持的特性.wideLines								= true;
	支持的特性.depthClamp								= true;
	支持的特性.depthBiasClamp							= true;
	支持的特性.shaderTessellationAndGeometryPointSize	= true;
	支持的特性.samplerAnisotropy						= true;
	支持的特性.imageCubeArray							= VK_TRUE;
	支持的特性.shaderInt64								= VK_TRUE;
	支持的特性.shaderInt16								= VK_TRUE;
	支持的特性.sampleRateShading						= VK_TRUE;
	支持的特性.shaderStorageImageMultisample			= VK_TRUE;
	支持的特性.fragmentStoresAndAtomics					= true;
	支持的特性.independentBlend							= true;
	
	
	

	VkPhysicalDeviceFeatures2 physicalDeviceFeatures2{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 };
	physicalDeviceFeatures2.features.shaderInt16 = true;



	float queue_优先级[11] = { 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0, 1.0, 1.0};
	vector<VkDeviceQueueCreateInfo>		列队创建信息(1);
	列队创建信息[0].sType				= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
	列队创建信息[0].pNext				= NULL;
	列队创建信息[0].queueFamilyIndex	= 逻辑设备.队列族索引;
	列队创建信息[0].queueCount			= 10;
	列队创建信息[0].pQueuePriorities	= queue_优先级;





	VkDeviceCreateInfo dev_info = {};
	dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;

	vector<const char*> extensions;
	VkDevice vk_逻辑设备;
	VkResult res;

	dev_info.queueCreateInfoCount = 列队创建信息.size();
	dev_info.pQueueCreateInfos = 列队创建信息.data();
	

	VkPhysicalDeviceScalarBlockLayoutFeaturesEXT ScalarBlockLayout{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT };
	ScalarBlockLayout.scalarBlockLayout = VK_TRUE;
	


	VkPhysicalDeviceVulkan11Features vulkan11Features = {};
	vulkan11Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;

	VkPhysicalDeviceFeatures2 deviceFeatures2 = {};
	deviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
	deviceFeatures2.pNext = &vulkan11Features;

	vkGetPhysicalDeviceFeatures2(物理设备, &deviceFeatures2);
	if (vulkan11Features.storageBuffer16BitAccess == VK_FALSE ||
		vulkan11Features.uniformAndStorageBuffer16BitAccess == VK_FALSE) {
		std::cout<<"16位访问不支持\n";
	}


	vulkan11Features.storageBuffer16BitAccess = VK_TRUE;
	vulkan11Features.uniformAndStorageBuffer16BitAccess = VK_TRUE;
	vulkan11Features.pNext = &ScalarBlockLayout;

	VkPhysicalDevice8BitStorageFeatures Bit8StorageFeatures{};
	Bit8StorageFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES;
	Bit8StorageFeatures.uniformAndStorageBuffer8BitAccess = true;
	Bit8StorageFeatures.storageBuffer8BitAccess = true;
	Bit8StorageFeatures.storagePushConstant8 = true;
	Bit8StorageFeatures.pNext = &vulkan11Features;
	
	
	VkPhysicalDeviceBufferDeviceAddressFeatures 启用GPU地址{};
	启用GPU地址.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES;
	启用GPU地址.bufferDeviceAddress = VK_TRUE;
	//启用GPU地址.bufferDeviceAddressCaptureReplay = VK_TRUE;
	//启用GPU地址.bufferDeviceAddressMultiDevice = VK_TRUE;
	启用GPU地址.pNext = &Bit8StorageFeatures;

	//VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES;
	//VkPhysicalDeviceDescriptorIndexingFeatures;
	if (是否有光追支持) {
		extensions = {
			VK_KHR_16BIT_STORAGE_EXTENSION_NAME,
			VK_KHR_SWAPCHAIN_EXTENSION_NAME,
			VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME,
			VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME,
			VK_KHR_RAY_QUERY_EXTENSION_NAME,

			VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME,
			VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME,
			VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME,
			VK_KHR_SPIRV_1_4_EXTENSION_NAME,
			VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME,
			VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME,
			VK_KHR_SHADER_CLOCK_EXTENSION_NAME,

			VK_EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME,
			VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME,
			VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME,
			//VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME,
			//VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME,
			//VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME,
		};
		dev_info.enabledExtensionCount = extensions.size();
		dev_info.ppEnabledExtensionNames = extensions.data();


		
		VkPhysicalDeviceShaderAtomicFloatFeaturesEXT F32原子操作{};
		F32原子操作.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT;
		F32原子操作.shaderBufferFloat32AtomicAdd = true;
		F32原子操作.shaderBufferFloat32Atomics = true;
		F32原子操作.shaderImageFloat32Atomics = true;
		F32原子操作.shaderImageFloat32AtomicAdd = true;
		F32原子操作.pNext = &启用GPU地址;


		VkPhysicalDeviceRayTracingPipelineFeaturesKHR 启用光追管线{};
		启用光追管线.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR;
		启用光追管线.rayTracingPipeline = VK_TRUE;
		启用光追管线.pNext = &F32原子操作;

		VkPhysicalDeviceShaderClockFeaturesKHR  启用着色器时钟{};
		启用着色器时钟.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR;
		启用着色器时钟.shaderDeviceClock = VK_TRUE;
		启用着色器时钟.shaderSubgroupClock = VK_TRUE;
		启用着色器时钟.pNext = &启用光追管线;

		VkPhysicalDeviceDescriptorIndexingFeaturesEXT indexingFeatures{};
		indexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
		indexingFeatures.runtimeDescriptorArray = VK_TRUE;
		indexingFeatures.shaderUniformTexelBufferArrayDynamicIndexing = true;
		indexingFeatures.shaderStorageTexelBufferArrayDynamicIndexing = true;
		indexingFeatures.shaderUniformTexelBufferArrayNonUniformIndexing = true;
		indexingFeatures.shaderSampledImageArrayNonUniformIndexing = true;
		indexingFeatures.descriptorBindingVariableDescriptorCount = true;
		indexingFeatures.shaderStorageImageArrayNonUniformIndexing = true;
		indexingFeatures.shaderStorageBufferArrayNonUniformIndexing = true;
		indexingFeatures.pNext = &启用着色器时钟;

		VkPhysicalDeviceVulkan13Features Vulkan13Features{};
		Vulkan13Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES;
		Vulkan13Features.pNext = &indexingFeatures;
		Vulkan13Features.maintenance4 = VK_TRUE;


		VkPhysicalDeviceAccelerationStructureFeaturesKHR 启用加速结构{};
		启用加速结构.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR;
		启用加速结构.accelerationStructure = VK_TRUE;
		启用加速结构.pNext = &Vulkan13Features;


		VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT 多重采样渲染到单纹理{};
		多重采样渲染到单纹理.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_FEATURES_EXT;
		多重采样渲染到单纹理.multisampledRenderToSingleSampled = VK_TRUE;
		多重采样渲染到单纹理.pNext = &启用加速结构;


		physicalDeviceFeatures2.features = 支持的特性;
		physicalDeviceFeatures2.pNext = &多重采样渲染到单纹理;
		dev_info.pNext = &physicalDeviceFeatures2;


		
		res = vkCreateDevice(物理设备, &dev_info, m_allocator, &vk_逻辑设备);
		if (res == VK_SUCCESS) {
			cout << "create vulkan ray Logical device SUCCESS"<< endl;
		}
		else {
			DEF_记录日志("vulkan 逻辑设备创建失败:" + std::to_string(res));
			cout << "create vulkan ray Logical device error : " << res << endl;
		}
	}
	else {
		extensions = {
				VK_KHR_SWAPCHAIN_EXTENSION_NAME,

				VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME,
				VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME,
				VK_KHR_SPIRV_1_4_EXTENSION_NAME,
				//VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME,
				VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME,
				VK_KHR_SHADER_CLOCK_EXTENSION_NAME,
				//VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME,
				//VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME,
				//VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME,
		};
		dev_info.enabledExtensionCount = extensions.size();
		dev_info.ppEnabledExtensionNames = extensions.data();


		VkPhysicalDeviceShaderClockFeaturesKHR  启用着色器时钟{};
		启用着色器时钟.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR;
		启用着色器时钟.shaderDeviceClock = VK_TRUE;
		启用着色器时钟.shaderSubgroupClock = VK_TRUE;
		启用着色器时钟.pNext = &启用GPU地址;

		VkPhysicalDeviceDescriptorIndexingFeaturesEXT indexingFeatures{};
		indexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
		indexingFeatures.runtimeDescriptorArray = VK_TRUE;
		indexingFeatures.shaderUniformTexelBufferArrayDynamicIndexing = true;
		indexingFeatures.shaderStorageTexelBufferArrayDynamicIndexing = true;
		indexingFeatures.shaderUniformTexelBufferArrayNonUniformIndexing = true;
		indexingFeatures.shaderSampledImageArrayNonUniformIndexing = true;
		indexingFeatures.descriptorBindingVariableDescriptorCount = true;
		indexingFeatures.pNext = &启用着色器时钟;

		//VkPhysicalDeviceScalarBlockLayoutFeaturesEXT ScalarBlockLayout{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT };
		//ScalarBlockLayout.scalarBlockLayout = VK_TRUE;
		//ScalarBlockLayout.pNext = &启用着色器时钟;

		physicalDeviceFeatures2.features = 支持的特性;
		physicalDeviceFeatures2.pNext = &启用着色器时钟;

		//dev_info.pEnabledFeatures = &支持的特性;
		dev_info.pNext = &physicalDeviceFeatures2;


		res = vkCreateDevice(物理设备, &dev_info, m_allocator, &vk_逻辑设备);
		if (res == VK_SUCCESS) {
			cout << "create vulkan Logical device SUCCESS" << endl;
		}
		else {
			DEF_记录日志("vulkan 无光追 逻辑设备创建失败:" + std::to_string(res));
			return {};
		}

		是否有光追支持 = false;
	}

	
	S_VK渲染环境* 渲染环境                      = (S_VK渲染环境*)malloc(sizeof(S_VK渲染环境));
	(*渲染环境)					                = { 0 };
	
	渲染环境->m_绘图框架 = this;
	渲染环境->m_设备属性						= prop->m_设备属性;
	渲染环境->m_内存属性						= prop->m_内存属性;
	渲染环境->m_设备							= vk_逻辑设备;
	渲染环境->交换链列队家族Offset				= 逻辑设备.队列族索引;
	渲染环境->绘图列队家族Offset				= 逻辑设备.队列族索引;

	渲染环境->m_命令开始信息.sType				= VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;	//给定结构体类型
	渲染环境->m_命令开始信息.pNext				= NULL;											//自定义数据的指针
	渲染环境->m_命令开始信息.flags				= 0;											//描述使用标志
	渲染环境->m_命令开始信息.pInheritanceInfo	= NULL;											//命令缓冲继承信息
	渲染环境->m_当前帧ID						= 0;
	渲染环境->m_列队ID							= 0;

	渲染环境->m_窗口UI合成通道              = nullptr;
	

	逻辑设备.设备		= (S_结构指针)vk_逻辑设备;
	逻辑设备.渲染环境	= (S_结构指针)渲染环境;


	VkFenceCreateInfo fenceCreateInfo{};
	fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
	fenceCreateInfo.flags = 0;
	vkCreateFence(vk_逻辑设备, &fenceCreateInfo, nullptr, &渲染环境->m_同步围栏);


	if (是否有光追支持) {
		f_vkFrame_初始化光追函数指针(this, vk_逻辑设备);
	}
	
	
	渲染环境->m_图形列队 = (VkQueue*)calloc(10, sizeof(VkQueue));
	for (uint8 i = 0; i < 10; ++i) {
		vkGetDeviceQueue(vk_逻辑设备, 渲染环境->绘图列队家族Offset, i, &(渲染环境->m_图形列队[i]));
	}
	
	逻辑设备.列队 = (S_结构指针*)渲染环境->m_图形列队;
	return 逻辑设备;
}

S_逻辑设备 S_VK框架::f_创建计算逻辑设备(S_逻辑设备& dev) {
	VkPhysicalDevice 物理设备 = (VkPhysicalDevice)dev.设备;
	S_物理设备属性* prop = (S_物理设备属性*)dev.渲染环境;


	vector<VkQueueFamilyProperties> 列队家族 = f_罗列物理设备列队家族(物理设备);
	uint32 列队家族数量 = 列队家族.size();

	//队列族索引
	S_逻辑设备 逻辑设备 = { 0, -1 };

	for (uint16 i = 0; i < 列队家族数量; ++i) {
		if (列队家族[i].queueFlags & VK_QUEUE_COMPUTE_BIT) {
			逻辑设备.队列族索引 = i;
			break;
		}
	}

	if (逻辑设备.队列族索引 < 0) return {0, -1};


	VkPhysicalDeviceFeatures 支持的特性 = {};
	支持的特性.shaderInt16 = true;
	支持的特性.shaderInt64 = true;
	支持的特性.shaderFloat64 = true;
	支持的特性.shaderStorageImageWriteWithoutFormat = true;
	支持的特性.shaderStorageImageReadWithoutFormat = true;



	float queue_优先级[11] = { 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0, 1.0, 1.0 };
	vector<VkDeviceQueueCreateInfo>		列队创建信息(1);
	列队创建信息[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
	列队创建信息[0].pNext = NULL;
	列队创建信息[0].queueFamilyIndex = 逻辑设备.队列族索引;
	列队创建信息[0].queueCount = 10;
	列队创建信息[0].pQueuePriorities = queue_优先级;




	VkDeviceCreateInfo dev_info = {};
	dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
	dev_info.queueCreateInfoCount = 列队创建信息.size();
	dev_info.pQueueCreateInfos = 列队创建信息.data();
	dev_info.enabledExtensionCount = 0;
	dev_info.ppEnabledExtensionNames = 0;
	dev_info.pEnabledFeatures = &支持的特性;


	VkDevice vk_dev;
	VkResult res = vkCreateDevice(物理设备, &dev_info, m_allocator, &vk_dev);
	assert(res == VK_SUCCESS);
	


	S_VK渲染环境* 绘图设备配置 = (S_VK渲染环境*)malloc(sizeof(S_VK渲染环境));
	(*绘图设备配置) = { };
	
	绘图设备配置->m_绘图框架                        = this;
	绘图设备配置->m_设备 = vk_dev;
	//绘图设备配置->m_设备属性						= prop->m_设备属性;
	//绘图设备配置->m_内存属性						= prop->m_内存属性;
	绘图设备配置->交换链列队家族Offset				= 逻辑设备.队列族索引;
	绘图设备配置->绘图列队家族Offset				= 逻辑设备.队列族索引;

	绘图设备配置->m_命令开始信息.sType				= VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;//给定结构体类型
	绘图设备配置->m_命令开始信息.pNext				= NULL;//自定义数据的指针
	绘图设备配置->m_命令开始信息.flags				= 0;//描述使用标志
	绘图设备配置->m_命令开始信息.pInheritanceInfo	= NULL;//命令缓冲继承信息

	绘图设备配置->m_当前帧ID = 0;
	绘图设备配置->m_列队ID = 0;

	绘图设备配置->m_图形列队 = (VkQueue*)calloc(10, sizeof(VkQueue));
	for (uint8 i = 0; i < 10; ++i) {
		vkGetDeviceQueue(vk_dev, 绘图设备配置->绘图列队家族Offset, i, &(绘图设备配置->m_图形列队[i]));
	}

	逻辑设备.渲染环境 = (S_结构指针)绘图设备配置;
	逻辑设备.设备 = (S_结构指针)vk_dev;


	return 逻辑设备;
}




bool S_VK框架::f_创建窗口绘制面(S_设备环境& dev, HINSTANCE& hInstance, HWND& hWnd, ivec2 size, E_MS次数 采样) {
	//S_VK绘图设备& 绘图设备配置 = *((S_VK绘图设备*)绘图设备);
	S_VK渲染环境& 绘图设备 = *((S_VK渲染环境*)f_df_get绘图环境(dev));


	VkWin32SurfaceCreateInfoKHR win32Surface创建信息 = {};
	win32Surface创建信息.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
	win32Surface创建信息.pNext = NULL;
	win32Surface创建信息.hinstance = hInstance;
	win32Surface创建信息.hwnd = hWnd;

	VkResult res = vkCreateWin32SurfaceKHR(m_Instance, &win32Surface创建信息, m_allocator, &绘图设备.m_绘制面);
	if (res != VK_SUCCESS) {
		DEF_记录日志("vulkan vkCreateWin32SurfaceKHR 创建渲染面失败:" + std::to_string(res));
		cout << "vkCreateWin32SurfaceKHR error" << endl;
	}


	vector<VkQueueFamilyProperties> 列队家族 = f_罗列物理设备列队家族(绘图设备.m_物理设备);
	uint32 列队家族数量 = 列队家族.size();

	//物理设备 交换链家族id 是否支持交换链
	vector<VkBool32> 是否支持交换链(列队家族数量);
	for (uint32 i = 0; i < 列队家族数量; ++i) {
		res = vkGetPhysicalDeviceSurfaceSupportKHR(绘图设备.m_物理设备, i, 绘图设备.m_绘制面, &是否支持交换链[i]);
		if (res != VK_SUCCESS) {
			DEF_记录日志("vulkan vkGetPhysicalDeviceSurfaceSupportKHR 没有取得渲染面设备:" + std::to_string(res));
			cout << "vkGetPhysicalDeviceSurfaceSupportKHR error" << endl;
		}
	}

	//////////////////////////////////////////////////////////////////////////
	//					 挑选绘图类和交换链类偏移ID							//
	//////////////////////////////////////////////////////////////////////////
	绘图设备.绘图列队家族Offset = UINT32_MAX;
	绘图设备.交换链列队家族Offset = UINT32_MAX;
	for (uint32 i = 0; i < 列队家族数量; ++i) {
		if (列队家族[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
			if (绘图设备.绘图列队家族Offset == UINT32_MAX) 绘图设备.绘图列队家族Offset = i;

			if (是否支持交换链[i]) {
				绘图设备.交换链列队家族Offset = i;
				break;
			}
		}
	}

	if (绘图设备.交换链列队家族Offset == UINT32_MAX || 绘图设备.交换链列队家族Offset == UINT32_MAX) {
		DEF_记录日志("vulkan 渲染面不支持显示模式:" + std::to_string(res));
		cout << "Surface error" << endl;
		return false;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////
	//									 物理设备呈现模式										//
	//////////////////////////////////////////////////////////////////////////////////////////////
	VkSurfaceCapabilitiesKHR 交换面功能 = {};
	res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(绘图设备.m_物理设备, 绘图设备.m_绘制面, &交换面功能);
	assert(res == VK_SUCCESS);
	uint32 当前模式数量 = 0;
	res = vkGetPhysicalDeviceSurfacePresentModesKHR(绘图设备.m_物理设备, 绘图设备.m_绘制面, &当前模式数量, NULL);
	assert(res == VK_SUCCESS);
	vector<VkPresentModeKHR> 当前模式(当前模式数量);
	res = vkGetPhysicalDeviceSurfacePresentModesKHR(绘图设备.m_物理设备, 绘图设备.m_绘制面, &当前模式数量, 当前模式.data());
	assert(res == VK_SUCCESS);

	//遍历显示模式列表
	VkPresentModeKHR 交换链呈现模式 = VK_PRESENT_MODE_FIFO_KHR;
	for (size_t i = 0; i < 当前模式数量; i++) {
		//如果也支持VK_PRESENT_MODE_MAILBOX_KHR模式，由于其效率高，便选用
		//若支持MAILBOX模式
		if (当前模式[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
			交换链呈现模式 = VK_PRESENT_MODE_MAILBOX_KHR;
			break;
		}
		//若支持IMMEDIATE模式
		if ((交换链呈现模式 != VK_PRESENT_MODE_MAILBOX_KHR) && (当前模式[i] == VK_PRESENT_MODE_IMMEDIATE_KHR)) {
			交换链呈现模式 = VK_PRESENT_MODE_IMMEDIATE_KHR;
		}
	}


	绘图设备.m_颜色图像格式 = f_取设备支持像素格式(绘图设备.m_物理设备, 绘图设备.m_绘制面);
	绘图设备.m_深度图像格式 = f_findDepthFormat(绘图设备.m_物理设备);


	f_创建交换链(&绘图设备, size, 0);
	f_创建交换链绘制缓存(dev, 采样);

	return true;
}


bool S_VK框架::f_创建同步围栏(S_逻辑设备& 逻辑dev) {
	VkDevice Device = (VkDevice)逻辑dev.设备;
	S_VK渲染环境* info = (S_VK渲染环境*)逻辑dev.渲染环境;

	VkFenceCreateInfo fenceInfo;//栅栏创建信息结构体实例
	fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;//结构体类型
	fenceInfo.pNext = NULL;//自定义数据的指针
	fenceInfo.flags = 0;//供将来使用的标志位
	vkCreateFence(Device, &fenceInfo, NULL, &info->m_同步围栏);

	return false;
}


bool S_VK框架::f_创建交换链(void* 绘图设备, ivec2 size, VkSwapchainKHR old_swapchain) {
	VkResult       res;
	S_VK渲染环境& 绘图设备配置 = *((S_VK渲染环境*)绘图设备);


	//////////////////////////////////////////////////////////////////////////////////////////////
	//									 物理设备呈现模式										//
	//////////////////////////////////////////////////////////////////////////////////////////////
	VkSurfaceCapabilitiesKHR 交换面功能 = {};
	res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(绘图设备配置.m_物理设备, 绘图设备配置.m_绘制面, &交换面功能);
	assert(res == VK_SUCCESS);
	uint32 当前模式数量 = 0;
	res = vkGetPhysicalDeviceSurfacePresentModesKHR(绘图设备配置.m_物理设备, 绘图设备配置.m_绘制面, &当前模式数量, NULL);
	assert(res == VK_SUCCESS);
	vector<VkPresentModeKHR> 当前模式(当前模式数量);
	res = vkGetPhysicalDeviceSurfacePresentModesKHR(绘图设备配置.m_物理设备, 绘图设备配置.m_绘制面, &当前模式数量, 当前模式.data());
	assert(res == VK_SUCCESS);

	VkPresentModeKHR 交换链呈现模式 = VK_PRESENT_MODE_FIFO_KHR;
	for (size_t i = 0; i < 当前模式数量; i++) {
		//如果也支持VK_PRESENT_MODE_MAILBOX_KHR模式，由于其效率高，便选用
		if (当前模式[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
			交换链呈现模式 = VK_PRESENT_MODE_MAILBOX_KHR;
			break;
		}
		if ((交换链呈现模式 != VK_PRESENT_MODE_MAILBOX_KHR) && (当前模式[i] == VK_PRESENT_MODE_IMMEDIATE_KHR)) {
			交换链呈现模式 = VK_PRESENT_MODE_IMMEDIATE_KHR;
		}
	}





	uvec2 视口大小 = { uint32(size.x), uint32(size.y) };
	if (视口大小.x < 交换面功能.minImageExtent.width) {
		视口大小.x = 交换面功能.minImageExtent.width;
	}
	else if (视口大小.x > 交换面功能.maxImageExtent.width) {
		视口大小.x = 交换面功能.maxImageExtent.width;
	}

	if (视口大小.y < 交换面功能.minImageExtent.height) {
		视口大小.y = 交换面功能.minImageExtent.height;
	}
	else if (视口大小.y > 交换面功能.maxImageExtent.height) {
		视口大小.y = 交换面功能.maxImageExtent.height;
	}

	绘图设备配置.绘制面大小.x = 视口大小.x;
	绘图设备配置.绘制面大小.y = 视口大小.y;
	//逻辑设备.m_视口大小.width = size.x;
	//逻辑设备.m_视口大小.height = size.y;
	VkSurfaceTransformFlagBitsKHR preTransform;
	if (交换面功能.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) {
		preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
	}
	else {
		preTransform = 交换面功能.currentTransform;
	}


	//////////////////////////////////////////////////////////////////////////////////
	//								查找支持透明模式								//
	//////////////////////////////////////////////////////////////////////////////////
	VkCompositeAlphaFlagBitsKHR 透明通道混合模式 = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
	VkCompositeAlphaFlagBitsKHR compositeAlphaFlags[4] = {
		VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
		VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR,
		VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR,
		VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR,
	};
	for (uint32_t i = 0; i < sizeof(compositeAlphaFlags); i++) {
		if (交换面功能.supportedCompositeAlpha & compositeAlphaFlags[i]) {
			透明通道混合模式 = compositeAlphaFlags[i];
			break;
		}
	}



	VkSwapchainCreateInfoKHR 交换链创建信息 = {};
	交换链创建信息.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
	交换链创建信息.pNext = NULL;
	交换链创建信息.surface = 绘图设备配置.m_绘制面;
	交换链创建信息.imageFormat = 绘图设备配置.m_颜色图像格式;
	交换链创建信息.minImageCount = 交换面功能.minImageCount;
	交换链创建信息.imageExtent.width = 视口大小.x;
	交换链创建信息.imageExtent.height = 视口大小.y;
	交换链创建信息.preTransform = preTransform;
	交换链创建信息.compositeAlpha = 透明通道混合模式;
	交换链创建信息.imageArrayLayers = 1;
	交换链创建信息.presentMode = 交换链呈现模式;
	交换链创建信息.oldSwapchain = VK_NULL_HANDLE;
	交换链创建信息.clipped = true;
	交换链创建信息.imageColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;								//色彩空间
	交换链创建信息.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT;	//图像用途
	交换链创建信息.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;									//图像共享模式
	交换链创建信息.queueFamilyIndexCount = 0;
	交换链创建信息.pQueueFamilyIndices = NULL;
	交换链创建信息.oldSwapchain = old_swapchain;

	uint32 queueFamilyIndices[2] = { 绘图设备配置.绘图列队家族Offset, 绘图设备配置.交换链列队家族Offset };
	if (queueFamilyIndices[0] != queueFamilyIndices[1]) {
		交换链创建信息.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
		交换链创建信息.queueFamilyIndexCount = 2;
		交换链创建信息.pQueueFamilyIndices = queueFamilyIndices;
	}



	res = vkCreateSwapchainKHR(绘图设备配置.m_设备, &交换链创建信息, NULL, &绘图设备配置.m_交换链);
	assert(res == VK_SUCCESS);
	if (res != VK_SUCCESS) {
		return false;
	}

	return true;
}

void S_VK框架::f_创建交换链绘制缓存(S_设备环境& dev, E_MS次数 采样) {
	VkResult       res;
	//S_VK绘图设备& 绘图设备配置 = *((S_VK绘图设备*)绘图设备);
	S_VK渲染环境& 绘图设备 = *((S_VK渲染环境*)f_df_get绘图环境(dev));

	//////////////////////////////////////////////////////////////////////////
	//							获取交换链中的图像							//
	//////////////////////////////////////////////////////////////////////////
	uint32 交换链数量 = 0;
	res = vkGetSwapchainImagesKHR(绘图设备.m_设备, 绘图设备.m_交换链, &交换链数量, nullptr);
	assert(res == VK_SUCCESS);
	VkImage* 交换链图像 = (VkImage*)malloc(交换链数量 * sizeof(VkImage));
	res = vkGetSwapchainImagesKHR(绘图设备.m_设备, 绘图设备.m_交换链, &交换链数量, 交换链图像);
	assert(res == VK_SUCCESS);



	/*******************************************************************************/
	//                              帧缓存创建
	/*******************************************************************************/
	S_Vk帧缓存* frameBuf = new S_Vk帧缓存(绘图设备.绘制面大小);

	uvec3 图像大小 = { 绘图设备.绘制面大小.x , 绘图设备.绘制面大小.y, 1 };
	uint32 用途 = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;

	if (采样 != E_MS次数::e_MS_1 && 0) {
		if (frameBuf->m_颜色图像) {
			f_tex_setSize(frameBuf->m_颜色图像, 绘图设备.绘制面大小);
		}
		else {
			frameBuf->m_颜色图像 = S_Vk图像管理::f_创建帧缓存图像(绘图设备.m_设备, 绘图设备.m_内存属性, 绘图设备.m_颜色图像格式, E_纹理维度类型::e_2D, 图像大小, 采样, 用途);
			frameBuf->m_颜色图像->m_Ctx = dev;
			//f_tex_创建图像纹理(dev, 图像大小, 绘图设备.m_颜色图像格式, E_纹理维度类型::e_2D, )
		}
		frameBuf->m_交换面颜色缓存.push_back((S_VkImage*)frameBuf->m_颜色图像);
		//frameBuf->m_交换面深度缓存.push_back((S_VkImage*)f_tex_创建深度纹理(dev, 图像大小, 采样, E_纹理维度类型::e_2D, E_纹理格式::e_tf_D32F));
	}
	
	for (uint32_t i_交换链图像 = 0; i_交换链图像 < 交换链数量; ++i_交换链图像) {
		S_VkImage* obj = S_Vk图像管理::f_创建图像视图(绘图设备.m_设备, 交换链图像[i_交换链图像], 绘图设备.m_颜色图像格式, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
		obj->m_Ctx = dev;
		frameBuf->m_交换面颜色缓存.push_back(obj);
		//frameBuf->m_交换面深度缓存.push_back((S_VkImage*)f_tex_创建深度纹理(dev, 图像大小, E_MS次数::e_MS_1, E_纹理维度类型::e_2D));

		//f_tex_渲染布局(obj);
		//f_tex_采样布局(obj);
	}
	



	VkSemaphoreCreateInfo 图像信号创建信息;
	图像信号创建信息.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
	图像信号创建信息.pNext = 0;
	图像信号创建信息.flags = 0;

	res = vkCreateSemaphore(绘图设备.m_设备, &图像信号创建信息, NULL, &绘图设备.m_图像获取信号量);
	assert(res == VK_SUCCESS);

	
	//if (绘图设备.m_窗口UI渲染通道 == nullptr) {
	//	绘图设备.m_窗口UI渲染通道 = f_fb_创建交换链渲染通道(绘图设备.m_设备, 绘图设备.m_颜色图像格式, f_vk_getVK图像格式(E_纹理格式::e_tf_D32F), 采样);
	//}
	if (绘图设备.m_窗口UI合成通道 == nullptr) {
		绘图设备.m_窗口UI合成通道 = f_fb_创建渲染通道(绘图设备.m_设备, 绘图设备.m_颜色图像格式, true);
	}
	
	frameBuf->m_颜色通道数量 = 1;
	if (1) {
		frameBuf->m_渲染通道 = 绘图设备.m_窗口UI合成通道;
		frameBuf->f_构建交换链缓存(绘图设备.m_设备, true, 采样 == E_MS次数::e_MS_1 ? 0 : 3);
		//f_frame_构建交换链缓存(*frameBuf, 采样 == E_MS次数::e_MS_1 ? false : true);
	}
	else {
		frameBuf->m_渲染通道 = 绘图设备.m_窗口UI合成通道;
		frameBuf->m_渲染通道 = f_fb_创建渲染通道(绘图设备.m_设备, 绘图设备.m_颜色图像格式, true);
		f_frame_构建交换链缓存(*frameBuf, false);
	}
	绘图设备.m_交换链帧缓存 = frameBuf;


	frameBuf->m_背景清除值[0].color.float32[0] = 0.1f;
	frameBuf->m_背景清除值[0].color.float32[1] = 0.1f;
	frameBuf->m_背景清除值[0].color.float32[2] = 0.1f;
	frameBuf->m_背景清除值[0].color.float32[3] = 1.0f;
	
	frameBuf->m_背景清除值[1].color.float32[0] = 0.1f;
	frameBuf->m_背景清除值[1].color.float32[1] = 0.1f;
	frameBuf->m_背景清除值[1].color.float32[2] = 0.1f;
	frameBuf->m_背景清除值[1].color.float32[3] = 1.0f;
	
	frameBuf->m_背景清除值[2].depthStencil.depth = 1.0;
	frameBuf->m_背景清除值[2].depthStencil.stencil = 0;

	frameBuf->m_开始渲染信息.clearValueCount = 3;
	frameBuf->m_开始渲染信息.renderArea.extent.width = 绘图设备.绘制面大小.x;
	frameBuf->m_开始渲染信息.renderArea.extent.height = 绘图设备.绘制面大小.y;
	frameBuf->m_开始渲染信息.renderPass = frameBuf->m_渲染通道;
}

void S_VK框架::f_重置交换链(S_设备环境& dev, ivec2 size, E_MS次数 采样) {
	//S_VK绘图设备& 绘图设备配置 = *((S_VK绘图设备*)绘图设备);
	S_VK渲染环境& 绘图设备 = *((S_VK渲染环境*)f_df_get绘图环境(dev));

	VkResult       res;
	VkSwapchainKHR old_swapchain = 绘图设备.m_交换链;
	res = vkDeviceWaitIdle(绘图设备.m_设备);
	assert(res == VK_SUCCESS);



	//销毁久的帧缓存
	绘图设备.m_交换链帧缓存->f_release(true);
	//if (绘图设备.m_渲染通道) vkDestroyRenderPass(绘图设备.m_设备, 绘图设备.m_渲染通道, m_allocator);


	f_创建交换链(&绘图设备, size, old_swapchain);

	if (old_swapchain) {
		vkDestroySwapchainKHR(绘图设备.m_设备, old_swapchain, m_allocator);
	}

	f_创建交换链绘制缓存(dev, 采样);
}


















//bool S_VK框架::f_创建命令缓存池(S_协处理设备& dev) {
//	VkDevice Device = (VkDevice)dev.设备;
//	S_VK渲染环境* info = (S_VK渲染环境*)dev.pNext;
//	
//	VkCommandPoolCreateInfo cmd_pool_info = {};
//	cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
//	cmd_pool_info.pNext = NULL;
//	cmd_pool_info.queueFamilyIndex = info->绘图列队家族Offset;
//	cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
//
//	VkResult res = vkCreateCommandPool(Device, &cmd_pool_info, m_allocator, &(info->m_命令缓存池));
//
//	assert(res == VK_SUCCESS);
//	
//	return true;
//}
//
//bool S_VK框架::f_创建命令缓存(S_协处理设备& dev, uint32 池ID, uint32 num) {
//	S_VK渲染环境* info = (S_VK渲染环境*)dev.pNext;
//	info->m_命令缓存 = f_vk创建命令缓存((S_VK渲染环境*)dev.pNext);
//	return true;
//	VkDevice Device = (VkDevice)dev.设备;
//	
//	VkCommandBufferAllocateInfo cmd = {};
//	cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
//	cmd.pNext = NULL;
//	cmd.commandPool = info->m_命令缓存池;
//	cmd.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
//	cmd.commandBufferCount = num;
//
//	VkResult res = vkAllocateCommandBuffers(Device, &cmd, &info->m_命令缓存);
//	assert(res == VK_SUCCESS);
//	return true;
//}


//bool S_VK框架::f_创建逻辑设备(uint32 物理设备key, const vector<const char*>& extensions) {
//	return false;
//}



VkFormat S_VK框架::f_取设备支持像素格式(VkPhysicalDevice& 物理设备, VkSurfaceKHR& surface)
{
	uint32 格式支持数量 = 0;
	VkResult res = vkGetPhysicalDeviceSurfaceFormatsKHR(物理设备, surface, &格式支持数量, NULL);
	assert(res == VK_SUCCESS);
	vector<VkSurfaceFormatKHR> 格式(格式支持数量);
	res = vkGetPhysicalDeviceSurfaceFormatsKHR(物理设备, surface, &格式支持数量, 格式.data());
	assert(res == VK_SUCCESS);

	if (格式支持数量 == 1 && 格式[0].format == VK_FORMAT_UNDEFINED) {
		return VK_FORMAT_B8G8R8A8_UNORM;
	}

	assert(格式支持数量 >= 1);
	return 格式[0].format;
}




bool S_VK框架::f_销毁交换链(S_Vk逻辑设备& dev) {
	//vkDestroySwapchainKHR(dev.m_Device, dev.m_交换链, NULL);
	return false;
}

bool S_VK框架::f_销毁命令列队(S_Vk逻辑设备 & dev) {
	//for (auto& e : dev.m_命令缓存池) {
		//vkFreeCommandBuffers(dev.m_Device, e, 1, cmd_bufs);
		//vkDestroyCommandPool(dev.m_Device, e, NULL);
	//}
	return false;
}

bool S_VK框架::f_销毁逻辑设备(vector<S_Vk逻辑设备>& devs) {
	for (auto& d : devs) {
		f_销毁交换链(d);
		f_销毁命令列队(d);
		
		vkDestroyDevice(d.m_Device, NULL);
	}
	
	return false;
}

bool S_VK框架::f_销毁实例(VkInstance& instance) {
	for (auto& k : m_逻辑设备) {
		f_销毁逻辑设备(k.second);
	}
	m_逻辑设备.clear();

	vkDestroyInstance(instance, NULL);
	return true;
}











bool S_VK框架::f_绘制(S_逻辑设备& dev) {
	VkDevice 设备 = (VkDevice)dev.设备;
	S_VK渲染环境* 绘图设备 = (S_VK渲染环境*)dev.渲染环境;
	

	VkResult res = vkAcquireNextImageKHR(设备, 绘图设备->m_交换链, UINT64_MAX, 绘图设备->m_图像获取信号量, VK_NULL_HANDLE, &绘图设备->m_当前帧ID);
	if (res == VK_ERROR_OUT_OF_DATE_KHR) {
		//recreateSwapChain();
		//return false;
	}
	else if (res != VK_SUCCESS && res != VK_SUBOPTIMAL_KHR) {
		throw std::runtime_error("failed to acquire swap chain image!");
	}
	//绘图设备配置->m_开始渲染信息.framebuffer = 绘图设备配置->m_交换链帧缓存->m_帧缓存[绘图设备配置->m_当前帧ID];
	vkResetCommandBuffer(绘图设备->m_命令缓存, 0);
	
	VkCommandBufferBeginInfo cmd_buf_info = {};
	cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	cmd_buf_info.pNext = NULL;
	cmd_buf_info.flags = 0;
	cmd_buf_info.pInheritanceInfo = NULL;
	res = vkBeginCommandBuffer(绘图设备->m_命令缓存, &cmd_buf_info);
	assert(res == VK_SUCCESS);


	绘图设备->m_交换链帧缓存->m_开始渲染信息.framebuffer = 绘图设备->m_交换链帧缓存->m_帧缓存[绘图设备->m_当前帧ID];
	vkCmdBeginRenderPass(绘图设备->m_命令缓存, &绘图设备->m_交换链帧缓存->m_开始渲染信息, VK_SUBPASS_CONTENTS_INLINE);



	vkCmdEndRenderPass(绘图设备->m_命令缓存);
	res = vkEndCommandBuffer(绘图设备->m_命令缓存);
	assert(res == VK_SUCCESS);


	VkSubmitInfo submitInfo = {};
	VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
	submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
	submitInfo.pWaitDstStageMask = waitStages;
	submitInfo.waitSemaphoreCount = 1;

	submitInfo.pWaitSemaphores = &绘图设备->m_图像获取信号量;
	
	submitInfo.commandBufferCount = 1;
	submitInfo.pCommandBuffers = &绘图设备->m_命令缓存;
	submitInfo.signalSemaphoreCount = 0;
	submitInfo.pSignalSemaphores = 0;

	
	if (vkQueueSubmit(绘图设备->m_图形列队[0], 1, &submitInfo, 绘图设备->m_同步围栏) != VK_SUCCESS) {
		throw std::runtime_error("failed to submit draw command buffer!");
	}
	do {	//等待渲染完毕
		res = vkWaitForFences(设备, 1, &绘图设备->m_同步围栏, VK_TRUE, FENCE_TIMEOUT);
	} while (res == VK_TIMEOUT);
	//vkWaitForFences(设备, 1, &绘图设备配置->m_同步围栏, VK_TRUE, FENCE_TIMEOUT);
	vkResetFences(设备, 1, &绘图设备->m_同步围栏);


	VkPresentInfoKHR presentInfo = {};
	presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
	presentInfo.waitSemaphoreCount = 0;
	presentInfo.pWaitSemaphores = 0;
	presentInfo.swapchainCount = 1;
	presentInfo.pSwapchains = &绘图设备->m_交换链;
	presentInfo.pImageIndices = &绘图设备->m_当前帧ID;

	VkResult result = vkQueuePresentKHR(绘图设备->m_图形列队[0], &presentInfo);
	//vkQueueWaitIdle(设备.m_交换列队);
	return false;
}

void S_VK框架::f_alloc(S_逻辑设备& dev) {
	VkDevice 设备 = (VkDevice)dev.设备;
	S_VK渲染环境* 绘图设备 = (S_VK渲染环境*)dev.渲染环境;
	
	VkResult res = vkAcquireNextImageKHR(设备, 绘图设备->m_交换链, UINT64_MAX, 绘图设备->m_图像获取信号量, VK_NULL_HANDLE, &绘图设备->m_当前帧ID);
	if (res == VK_ERROR_OUT_OF_DATE_KHR) {
		//recreateSwapChain();
		//return false;
	}
	else if (res != VK_SUCCESS && res != VK_SUBOPTIMAL_KHR) {
		throw std::runtime_error("failed to acquire swap chain image!");
	}

	绘图设备->m_交换链帧缓存->m_开始渲染信息.framebuffer = 绘图设备->m_交换链帧缓存->m_帧缓存[绘图设备->m_当前帧ID];

	//绘图设备->m_开始渲染信息.framebuffer = 绘图设备->m_交换链帧缓存->m_帧缓存[绘图设备->m_当前帧ID];
	//绘图设备->m_开始渲染信息.clearValueCount = 绘图设备->m_交换链帧缓存->m_全屏数量;
	//绘图设备->m_开始渲染信息.pClearValues = 绘图设备->m_交换链帧缓存->m_背景清除值;
	//绘图设备->m_开始渲染信息.renderPass = 绘图设备->m_交换链帧缓存->m_渲染通道;
	vkResetCommandBuffer(绘图设备->m_命令缓存, 0);


	VkCommandBufferBeginInfo cmd_buf_info = {};
	cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	cmd_buf_info.pNext = NULL;
	cmd_buf_info.flags = 0;
	cmd_buf_info.pInheritanceInfo = NULL;
	res = vkBeginCommandBuffer(绘图设备->m_命令缓存, &cmd_buf_info);
	assert(res == VK_SUCCESS);
	vkCmdBeginRenderPass(绘图设备->m_命令缓存, &绘图设备->m_交换链帧缓存->m_开始渲染信息, VK_SUBPASS_CONTENTS_INLINE);//启动渲染通道
}

void S_VK框架::f_End(S_逻辑设备& dev) {
	VkDevice 设备 = (VkDevice)dev.设备;
	S_VK渲染环境* 绘图设备配置 = (S_VK渲染环境*)dev.渲染环境;

	VkResult res;
	vkCmdEndRenderPass(绘图设备配置->m_命令缓存);
	res = vkEndCommandBuffer(绘图设备配置->m_命令缓存);
	assert(res == VK_SUCCESS);


	VkSubmitInfo submitInfo = {};
	//VkSemaphore waitSemaphores[] = { 绘图设备配置->m_清屏信号 };
	VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
	submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
	submitInfo.pWaitDstStageMask = waitStages;
	submitInfo.waitSemaphoreCount = 1;

	submitInfo.pWaitSemaphores = &绘图设备配置->m_图像获取信号量;
	submitInfo.commandBufferCount = 1;

	submitInfo.pCommandBuffers = &绘图设备配置->m_命令缓存;
	submitInfo.signalSemaphoreCount = 0;
	submitInfo.pSignalSemaphores = 0;


	res = vkQueueSubmit(绘图设备配置->m_图形列队[0], 1, &submitInfo, 绘图设备配置->m_同步围栏);
	
	//if ( != VK_SUCCESS) {
	//	throw std::runtime_error("failed to submit draw command buffer!");
	//}
	VkPresentInfoKHR presentInfo = {};
	presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
	presentInfo.waitSemaphoreCount = 0;
	presentInfo.pWaitSemaphores = 0;
	presentInfo.swapchainCount = 1;
	presentInfo.pSwapchains = &绘图设备配置->m_交换链;
	presentInfo.pImageIndices = &绘图设备配置->m_当前帧ID;


	do {
		res = vkWaitForFences(设备, 1, &绘图设备配置->m_同步围栏, VK_TRUE, FENCE_TIMEOUT);
	} while (res == VK_TIMEOUT);
	//vkWaitForFences(设备, 1, &绘图设备配置->m_同步围栏, VK_TRUE, FENCE_TIMEOUT);
	vkResetFences(设备, 1, &绘图设备配置->m_同步围栏);

	res = vkQueuePresentKHR(绘图设备配置->m_图形列队[0], &presentInfo);
	//res = vkQueueWaitIdle(绘图设备配置->m_图形列队[0]);
}

void S_VK框架::f_beginRender(S_渲染环境* 绘图设备配置) {
	S_VK渲染环境* 绘图设备 = (S_VK渲染环境*)绘图设备配置;
	
	VkResult res = vkAcquireNextImageKHR(绘图设备->m_设备, 绘图设备->m_交换链, UINT64_MAX, 绘图设备->m_图像获取信号量, VK_NULL_HANDLE, &绘图设备->m_当前帧ID);
	if (res == VK_ERROR_OUT_OF_DATE_KHR) {
		//recreateSwapChain();
		return;
	}
	else if (res != VK_SUCCESS && res != VK_SUBOPTIMAL_KHR) {
		throw std::runtime_error("failed to acquire swap chain image!");
	}

	绘图设备->m_交换链帧缓存->m_开始渲染信息.framebuffer = 绘图设备->m_交换链帧缓存->m_帧缓存[绘图设备->m_当前帧ID];
	
	vkResetCommandBuffer(绘图设备->m_命令缓存, 0);



	VkCommandBufferBeginInfo cmd_buf_info = {};
	cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	cmd_buf_info.pNext = NULL;
	cmd_buf_info.flags = 0;
	cmd_buf_info.pInheritanceInfo = NULL;
	res = vkBeginCommandBuffer(绘图设备->m_命令缓存, &cmd_buf_info);
	assert(res == VK_SUCCESS);

	vkCmdBeginRenderPass(绘图设备->m_命令缓存, &绘图设备->m_交换链帧缓存->m_开始渲染信息, VK_SUBPASS_CONTENTS_INLINE);
}

void S_VK框架::f_endRender(S_渲染环境* 绘图设备配置) {
	S_VK渲染环境* 绘图配置 = (S_VK渲染环境*)绘图设备配置;

	VkResult res;
	vkCmdEndRenderPass(绘图配置->m_命令缓存);
	res = vkEndCommandBuffer(绘图配置->m_命令缓存);	
	assert(res == VK_SUCCESS);



	VkSubmitInfo submitInfo = {};
	//VkSemaphore waitSemaphores[] = { 绘图设备配置->m_清屏信号 };
	VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
	submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
	submitInfo.pWaitDstStageMask = waitStages;
	submitInfo.waitSemaphoreCount = 1;

	submitInfo.pWaitSemaphores = &绘图配置->m_图像获取信号量;
	submitInfo.commandBufferCount = 1;

	submitInfo.pCommandBuffers = &绘图配置->m_命令缓存;
	submitInfo.signalSemaphoreCount = 0;
	submitInfo.pSignalSemaphores = 0;


	res = vkQueueSubmit(绘图配置->m_图形列队[0], 1, &submitInfo, 绘图配置->m_同步围栏);
	//vkDeviceWaitIdle(绘图配置->m_设备);

	VkPresentInfoKHR presentInfo = {};
	presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
	presentInfo.waitSemaphoreCount = 0;
	presentInfo.pWaitSemaphores = 0;
	presentInfo.swapchainCount = 1;
	presentInfo.pSwapchains = &绘图配置->m_交换链;
	presentInfo.pImageIndices = &绘图配置->m_当前帧ID;


	do {	//等待渲染完毕
		res = vkWaitForFences(绘图配置->m_设备, 1, &绘图配置->m_同步围栏, VK_TRUE, FENCE_TIMEOUT);
	} while (res == VK_TIMEOUT);
	vkResetFences(绘图配置->m_设备, 1, &绘图配置->m_同步围栏);

	res = vkQueuePresentKHR(绘图配置->m_图形列队[0], &presentInfo);
}






vector<VkQueueFamilyProperties> S_VK框架::f_罗列物理设备列队家族(VkPhysicalDevice& 物理设备) {
	return f_vk_罗列物理设备列队家族(物理设备);
}


void f_vkFrame_初始化光追函数指针(S_VK框架* VK框架, VkDevice 设备) {
	VK框架->vkCreateAccelerationStructure = reinterpret_cast<PFN_vkCreateAccelerationStructureKHR>(vkGetDeviceProcAddr(设备, "vkCreateAccelerationStructureKHR"));
	VK框架->vkDestroyAccelerationStructure = reinterpret_cast<PFN_vkDestroyAccelerationStructureKHR>(vkGetDeviceProcAddr(设备, "vkDestroyAccelerationStructureKHR"));
	VK框架->vkCmdBuildAccelerationStructures = reinterpret_cast<PFN_vkCmdBuildAccelerationStructuresKHR>(vkGetDeviceProcAddr(设备, "vkCmdBuildAccelerationStructuresKHR"));
	VK框架->vkBuildAccelerationStructures = reinterpret_cast<PFN_vkBuildAccelerationStructuresKHR>(vkGetDeviceProcAddr(设备, "vkBuildAccelerationStructuresKHR"));
	VK框架->vkGetAccelerationStructureBuildSizes = reinterpret_cast<PFN_vkGetAccelerationStructureBuildSizesKHR>(vkGetDeviceProcAddr(设备, "vkGetAccelerationStructureBuildSizesKHR"));
	VK框架->vkGetAccelerationStructureDeviceAddress = reinterpret_cast<PFN_vkGetAccelerationStructureDeviceAddressKHR>(vkGetDeviceProcAddr(设备, "vkGetAccelerationStructureDeviceAddressKHR"));
	VK框架->vkCreateRayTracingPipelines = reinterpret_cast<PFN_vkCreateRayTracingPipelinesKHR>(vkGetDeviceProcAddr(设备, "vkCreateRayTracingPipelinesKHR"));
	VK框架->vkGetRayTracingShaderGroupHandles = reinterpret_cast<PFN_vkGetRayTracingShaderGroupHandlesKHR>(vkGetDeviceProcAddr(设备, "vkGetRayTracingShaderGroupHandlesKHR"));
	VK框架->vkCmdTraceRays = reinterpret_cast<PFN_vkCmdTraceRaysKHR>(vkGetDeviceProcAddr(设备, "vkCmdTraceRaysKHR"));
}





void f_vk创建命令缓存池(S_VK渲染环境* info) {
	VkCommandPoolCreateInfo cmd_pool_info = {};
	cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
	cmd_pool_info.pNext = NULL;
	cmd_pool_info.queueFamilyIndex = info->绘图列队家族Offset;
	cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;

	VkResult res = vkCreateCommandPool(info->m_设备, &cmd_pool_info, nullptr, &(info->m_命令缓存池));

	assert(res == VK_SUCCESS);
}

VkCommandBuffer f_vk创建命令缓存(S_VK渲染环境* 绘图设备, uint32 num, bool 创建新池) {
	VkCommandPool pool;
	if (创建新池) {
		VkCommandPoolCreateInfo cmd_pool_info = {};
		cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
		cmd_pool_info.pNext = NULL;
		cmd_pool_info.queueFamilyIndex = 绘图设备->绘图列队家族Offset;
		cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;

		VkResult res = vkCreateCommandPool(绘图设备->m_设备, &cmd_pool_info, nullptr, &pool);

		static std::vector<VkCommandPool> m_命令缓存池容器;
		m_命令缓存池容器.push_back(pool);
	}
	else {
		pool = 绘图设备->m_命令缓存池;
	}

	VkCommandBufferAllocateInfo cmd = {};
	cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
	cmd.pNext = NULL;
	cmd.commandPool = pool;
	cmd.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
	cmd.commandBufferCount = num;

	VkCommandBuffer buf = nullptr;
	VkResult res = vkAllocateCommandBuffers(绘图设备->m_设备, &cmd, &buf);
	assert(res == VK_SUCCESS);
	return buf;
}

void f_vk销毁命令缓存(S_VK渲染环境* 绘图设备, VkCommandBuffer cmd) {
	vkFreeCommandBuffers(绘图设备->m_设备, 绘图设备->m_命令缓存池, 1, &cmd);
}

void f_vk绑定命令缓存(S_VK渲染环境* 绘图设备, VkCommandBuffer cmd, bool 重置命令缓存) {
	if (重置命令缓存) {
		vkResetCommandBuffer(cmd, 0);
	}
	vkBeginCommandBuffer(cmd, &绘图设备->m_命令开始信息);
}

void f_vk刷新命令缓存(S_VK渲染环境* 绘图设备, VkCommandBuffer cmd, bool 释放命令缓存) {
	vkEndCommandBuffer(cmd);

	VkSubmitInfo submitInfo{ VK_STRUCTURE_TYPE_SUBMIT_INFO };
	submitInfo.commandBufferCount = 1;
	submitInfo.pCommandBuffers = &cmd;
	
	VkFenceCreateInfo fenceInfo{ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO };
	VkFence fence;
	vkCreateFence(绘图设备->m_设备, &fenceInfo, nullptr, &fence);
	
	vkQueueSubmit(*绘图设备->m_图形列队, 1, &submitInfo, fence);
	
	vkWaitForFences(绘图设备->m_设备, 1, &fence, VK_TRUE, 100000000);
	vkDestroyFence(绘图设备->m_设备, fence, nullptr);
	if (释放命令缓存) {
		vkFreeCommandBuffers(绘图设备->m_设备, 绘图设备->m_命令缓存池, 1, &cmd);
	}
}





void f_vk创建命令缓存(void* 绘图设备, uint32 池ID, uint32 num) {
	S_VK渲染环境& info = *((S_VK渲染环境*)绘图设备);

	VkCommandBufferAllocateInfo cmd = {};
	cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
	cmd.pNext = NULL;
	cmd.commandPool = info.m_命令缓存池;
	cmd.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
	cmd.commandBufferCount = num;

	VkCommandBuffer buf;
	VkResult res = vkAllocateCommandBuffers(info.m_设备, &cmd, &info.m_命令缓存);

	assert(res == VK_SUCCESS);
}

void f_vk创建同步围栏(void* 绘图设备) {
	S_VK渲染环境& info = *((S_VK渲染环境*)绘图设备);
	
	VkFenceCreateInfo fenceInfo;									//栅栏创建信息结构体实例
	fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;			//结构体类型
	fenceInfo.pNext = NULL;											//自定义数据的指针
	fenceInfo.flags = 0;											//供将来使用的标志位
	vkCreateFence(info.m_设备, &fenceInfo, NULL, &info.m_同步围栏);
}


typedef struct {
	uint64           m_Type;
	uint64           m_线程数量;
	VkDevice         m_逻辑设备;
	VkCommandBuffer* m_命令缓存;

	VkCommandPool            m_命令池;
	VkCommandBufferBeginInfo m_开始信息;
}S_Real子集绘图命令;



S_子集绘图命令* f_bd_创建子集绘图命令(S_渲染环境* 绘图设备, uint32 线程数量) {
	S_VK渲染环境& info = *((S_VK渲染环境*)绘图设备);
	S_Real子集绘图命令* 子集命令 = (S_Real子集绘图命令*)malloc(sizeof(S_Real子集绘图命令));
	VkResult res;

	static VkCommandBufferInheritanceInfo InheritanceInfo{};
	InheritanceInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;


	子集命令->m_Type = 0;
	子集命令->m_线程数量 = 线程数量;
	子集命令->m_逻辑设备 = info.m_设备;
	子集命令->m_开始信息 = info.m_命令开始信息;
	子集命令->m_开始信息.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
	子集命令->m_开始信息.pInheritanceInfo = &InheritanceInfo;


	VkCommandPoolCreateInfo 命令池{};
	命令池.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
	命令池.queueFamilyIndex = info.绘图列队家族Offset;
	命令池.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
	res = vkCreateCommandPool(info.m_设备, &命令池, nullptr, &子集命令->m_命令池);
	assert(res == VK_SUCCESS);


	VkCommandBufferAllocateInfo cmd = {};
	cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
	cmd.pNext = NULL;
	cmd.commandPool = 子集命令->m_命令池;
	cmd.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
	cmd.commandBufferCount = 线程数量;
	assert(res == VK_SUCCESS);


	子集命令->m_命令缓存 = (VkCommandBuffer*)calloc(线程数量, sizeof(VkCommandBuffer));
	res = vkAllocateCommandBuffers(info.m_设备, &cmd, 子集命令->m_命令缓存);


	//vkCmdExecuteCommands(info.m_命令缓存, 线程数量, 子集命令->m_命令缓存);
	return (S_子集绘图命令*)子集命令;
}

void f_Draw_Begin(S_子集绘图命令* 绘图命令, uint8 id) {
	S_Real子集绘图命令& info = *((S_Real子集绘图命令*)绘图命令);

	vkResetCommandBuffer(info.m_命令缓存[id], 0);
	vkBeginCommandBuffer(info.m_命令缓存[id], &info.m_开始信息);
}

void f_Draw_end(S_子集绘图命令* 绘图命令, uint8 id) {
	S_Real子集绘图命令& info = *((S_Real子集绘图命令*)绘图命令);

	vkEndCommandBuffer(info.m_命令缓存[id]);
}


/*PFN_vkGetBufferDeviceAddressKHR vkGetBufferDeviceAddressKHR;
PFN_vkCreateAccelerationStructureKHR vkCreateAccelerationStructureKHR;
PFN_vkDestroyAccelerationStructureKHR vkDestroyAccelerationStructureKHR;
PFN_vkGetAccelerationStructureBuildSizesKHR vkGetAccelerationStructureBuildSizesKHR;
PFN_vkGetAccelerationStructureDeviceAddressKHR vkGetAccelerationStructureDeviceAddressKHR;
PFN_vkBuildAccelerationStructuresKHR vkBuildAccelerationStructuresKHR;
PFN_vkCmdBuildAccelerationStructuresKHR vkCmdBuildAccelerationStructuresKHR;
PFN_vkCmdTraceRaysKHR vkCmdTraceRaysKHR;
PFN_vkGetRayTracingShaderGroupHandlesKHR vkGetRayTracingShaderGroupHandlesKHR;
PFN_vkCreateRayTracingPipelinesKHR vkCreateRayTracingPipelinesKHR;*/




void* f_df_getVK实例(S_绘图框架* df) {
	S_VK框架* self = dynamic_cast<S_VK框架*>(df);
	if (self) {
		return self->m_Instance;
	}
	return nullptr;
}

void* f_df_getVK设备(S_设备环境& ctx) {
	return ctx.m_逻辑设备.设备;
}


void f_df_销毁2D绘制缓存(S_设备环境& ctx) {
	auto* df = f_vk_get绘图框架(ctx);
}


void f_df_创建2D管线布局集(S_设备环境& ctx) {
	auto* df = f_vk_get绘图框架(ctx);
	df->m_2D绘图管线布局集 = (S_结构对象*)malloc(sizeof(S_2D绘图管线布局集));

	f_pipe_着色线管布局创建(ctx);
}
void f_df_销毁2D绘制参数布局(S_设备环境& ctx) {
	auto* df = f_vk_get绘图框架(ctx);

	f_pipe_着色线管布局销毁(ctx);

	free(df->m_2D绘图管线布局集);
}




void f_df_windowSurface(S_设备环境& ctx, S_WindowSurface* surface, ivec2 size) {
	auto dc = f_vk_get绘图环境(ctx);

	S_vk_window& ws = *((S_vk_window*)surface);

	ws.viewSize = size;
	f_createSwapchain(ctx, ws, _uVec2(size));

	VkSemaphoreCreateInfo 图像信号创建信息;
	图像信号创建信息.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
	图像信号创建信息.pNext = 0;
	图像信号创建信息.flags = 0;
	auto res = vkCreateSemaphore(dc->m_设备, &图像信号创建信息, NULL, &ws.m_vk_Semaphore);
	if (res != VK_SUCCESS) {
		DEF_记录日志("vulkan vkCreateSemaphore 创建失败:" + std::to_string(res) + " " + std::string(__FILE__) + " 行:" + std::to_string(__LINE__));
	}
	assert(res == VK_SUCCESS);
}

S_vk_window* f_df_win32Surface(S_设备环境& ctx, HINSTANCE& hInstance, HWND& hWnd, ivec2 size, E_MS次数 采样) {
	auto rf = f_vk_get绘图框架(ctx);
	auto dc = f_vk_get绘图环境(ctx);

	S_vk_window* surface = (S_vk_window*)malloc(sizeof(S_vk_window));
	(*surface) = {};
	

	VkWin32SurfaceCreateInfoKHR win32Surface创建信息 = {};
	win32Surface创建信息.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
	win32Surface创建信息.pNext = NULL;
	win32Surface创建信息.hinstance = hInstance;
	win32Surface创建信息.hwnd = hWnd;

	VkResult res = vkCreateWin32SurfaceKHR(rf->m_Instance, &win32Surface创建信息, nullptr, &surface->m_vk_surface);
	if (res != VK_SUCCESS) {
		DEF_记录日志("vulkan vkCreateWin32SurfaceKHR 创建失败:" + std::to_string(res) + " " + std::string(__FILE__) + " 行:" + std::to_string(__LINE__));
		cout << "vkCreateWin32SurfaceKHR error" << endl;
	}
	
	f_df_windowSurface(ctx, (S_WindowSurface*)surface, size);
	return surface;
}

void f_df_release_win32Surface(S_设备环境& ctx, S_WindowSurface* surface) {
	auto rf = f_vk_get绘图框架(ctx);
	auto dc = *f_vk_get绘图环境(ctx);
	S_vk_window& ws = *((S_vk_window*)surface);

	vkDestroySemaphore(dc.m_设备, ws.m_vk_Semaphore, nullptr);
	vkDestroySwapchainKHR(dc.m_设备, ws.m_vk_swapchain, nullptr);

	
	S_Vk帧缓存* vkFrame = (S_Vk帧缓存*)ws.m_Frame;
	for (uint32 i = 0; i < vkFrame->m_帧缓存.size(); ++i) {
		f_tex_销毁图像视图(dc.m_设备, *dynamic_cast<S_VkImage*>(ws.m_交换面颜色缓存[i]));
	}
	free(ws.m_交换面颜色缓存);
	f_fb_销毁UI合成帧缓存(ctx, ws.m_Frame);
	
}

void f_df_win32Surface_resize(S_设备环境& ctx, S_WindowSurface* surface, uvec2 size) {
	S_vk_window& ws = *((S_vk_window*)surface);
	auto dc = *f_vk_get绘图环境(ctx);

	vkDestroySwapchainKHR(dc.m_设备, ws.m_vk_swapchain, nullptr);

	S_Vk帧缓存* vkFrame = (S_Vk帧缓存*)ws.m_Frame;
	for (uint32 i = 0; i < vkFrame->m_帧缓存.size(); ++i) {
		f_tex_销毁图像视图(dc.m_设备, *dynamic_cast<S_VkImage*>(ws.m_交换面颜色缓存[i]));
	}


	f_vk_创建交换链(ctx, ws, size, 0);
	f_vk_重置交换链图像(ctx, ws, size, vkFrame->m_帧缓存.size());

	f_fb_重置UI合成帧缓存(ctx, ws.m_Frame, size, ws.m_交换面颜色缓存);
}


void f_df_render_begin(S_WindowSurface* surface, S_渲染环境* 渲染环境) {
	S_vk_window& vkSurface = *(S_vk_window*)surface;
	S_VK渲染环境& vk绘图设备 = *(S_VK渲染环境*)渲染环境;

	VkResult res = vkAcquireNextImageKHR(vk绘图设备.m_设备, vkSurface.m_vk_swapchain, UINT64_MAX, vkSurface.m_vk_Semaphore, VK_NULL_HANDLE, &vkSurface.m_交换链ID);
	if (res == VK_ERROR_OUT_OF_DATE_KHR) {
		//recreateSwapChain();
		return;
	}
	else if (res != VK_SUCCESS && res != VK_SUBOPTIMAL_KHR) {
		throw std::runtime_error("failed to acquire swap chain image!");
	}

	S_Vk帧缓存* frame = (S_Vk帧缓存*)vkSurface.m_Frame;
	frame->m_开始渲染信息.framebuffer = frame->m_帧缓存[vkSurface.m_交换链ID];

	vkResetCommandBuffer(vk绘图设备.m_命令缓存, 0);



	VkCommandBufferBeginInfo cmd_buf_info = {};
	cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	cmd_buf_info.pNext = NULL;
	cmd_buf_info.flags = 0;
	cmd_buf_info.pInheritanceInfo = NULL;
	res = vkBeginCommandBuffer(vk绘图设备.m_命令缓存, &cmd_buf_info);
	assert(res == VK_SUCCESS);

	vkCmdBeginRenderPass(vk绘图设备.m_命令缓存, &frame->m_开始渲染信息, VK_SUBPASS_CONTENTS_INLINE);
}

void f_df_render_end(S_WindowSurface* surface, S_渲染环境* 渲染环境) {
	S_VK渲染环境& vk绘图设备 = *(S_VK渲染环境*)渲染环境;
	S_vk_window& vkSurface = *(S_vk_window*)surface;

	VkResult res;
	vkCmdEndRenderPass(vk绘图设备.m_命令缓存);
	res = vkEndCommandBuffer(vk绘图设备.m_命令缓存);	
	assert(res == VK_SUCCESS);



	VkSubmitInfo submitInfo = {};
	//VkSemaphore waitSemaphores[] = { 绘图设备配置->m_清屏信号 };
	VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
	submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
	submitInfo.pWaitDstStageMask = waitStages;
	submitInfo.waitSemaphoreCount = 1;

	submitInfo.pWaitSemaphores = &vkSurface.m_vk_Semaphore;
	submitInfo.commandBufferCount = 1;

	submitInfo.pCommandBuffers = &vk绘图设备.m_命令缓存;
	submitInfo.signalSemaphoreCount = 0;
	submitInfo.pSignalSemaphores = 0;


	res = vkQueueSubmit(vk绘图设备.m_图形列队[0], 1, &submitInfo, vk绘图设备.m_同步围栏);
	//vkDeviceWaitIdle(绘图配置->m_设备);

	VkPresentInfoKHR presentInfo = {};
	presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
	presentInfo.waitSemaphoreCount = 0;
	presentInfo.pWaitSemaphores = 0;
	presentInfo.swapchainCount = 1;
	presentInfo.pSwapchains = &vkSurface.m_vk_swapchain;
	presentInfo.pImageIndices = &vkSurface.m_交换链ID;


	do {	//等待渲染完毕
		res = vkWaitForFences(vk绘图设备.m_设备, 1, &vk绘图设备.m_同步围栏, VK_TRUE, FENCE_TIMEOUT);
	} while (res == VK_TIMEOUT);
	vkResetFences(vk绘图设备.m_设备, 1, &vk绘图设备.m_同步围栏);

	res = vkQueuePresentKHR(vk绘图设备.m_图形列队[0], &presentInfo);
	if (res != VK_SUCCESS) {
		DEF_记录日志("vulkan vkQueuePresentKHR:" + std::to_string(res) + " " + std::string(__FILE__) + " 行:" + std::to_string(__LINE__));
	}
	
}


